package de.slash.jplaylistextractor;

import de.slash.jplaylistextractor.common.ExceptionHandler;
import de.slash.jplaylistextractor.model.Media;
import de.slash.jplaylistextractor.model.WplPlaylist;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * User: Slash
 * Date: 26.02.2012
 * Time: 14:56
 */
public class PlaylistImporter
{
    private ExceptionHandler exceptionHandler;

    PlaylistImporter(ExceptionHandler pExceptionHandler)
    {
        exceptionHandler = pExceptionHandler;
    }

    public ArrayList<Media> importWPLList(String pPath)
    {
        WplPlaylist wplPlaylist = null;

        try
        {
            JAXBContext context = JAXBContext.newInstance(WplPlaylist.class);
            Unmarshaller m = context.createUnmarshaller();
            File file = new File(pPath);
            wplPlaylist = (WplPlaylist) m.unmarshal(file);
        }
        catch (Exception e)
        {
            exceptionHandler.handleException(e);
        }

        return _convertToMediaList(wplPlaylist, pPath);
    }

    public ArrayList<Media> importITunesXmlList(String pPath)
    {
        ArrayList<Media> medias = new ArrayList<Media>();

        try
        {
            Document doc = new SAXBuilder().build(pPath);
            Element firstDictElement = (Element) doc.getRootElement().getChildren().get(0);
            List firstDictElementChilds = firstDictElement.getChildren();

            for (int i = 0; i < firstDictElementChilds.size(); i++)
            {
                Element firstDictChildElement = (Element) firstDictElementChilds.get(i);

                if (firstDictChildElement.getQualifiedName().equals("dict"))
                {
                    List secondDictElement = firstDictChildElement.getChildren();

                    for (int j = 0; j < secondDictElement.size(); j++)
                    {
                        Element secondDictChildElement = (Element) secondDictElement.get(j);

                        if (secondDictChildElement.getQualifiedName().equals("dict"))
                        {
                            List thirdDictElement = secondDictChildElement.getChildren();

                            for (int k = 0; k < thirdDictElement.size(); k++)
                            {
                                Element thirdDictChildElement = (Element) thirdDictElement.get(k);

                                if (thirdDictChildElement.getText().equals("Location"))
                                {
                                    thirdDictChildElement = (Element) thirdDictElement.get(k + 1);
                                    medias.add(new Media(thirdDictChildElement.getText()));
                                }
                            }
                        }
                    }
                }
            }
        }
        catch (Exception e)
        {
            exceptionHandler.handleException(e);
        }

        return medias;
    }

    public ArrayList<Media> importM3UList(String pPath)
    {
        ArrayList<Media> medias = new ArrayList<Media>();

        try
        {
            File file = new File(pPath);
            BufferedReader in = new BufferedReader(new FileReader(file));
            String line;

            while ((line = in.readLine()) != null)
            {
                if (!line.startsWith("#EXT") && !line.isEmpty())
                {
                    File mediaFile = new File(line);

                    if (!mediaFile.isAbsolute())
                    {
                        medias.add(new Media(_convertToAbsolutePath(line, pPath)));
                    }
                    else
                    {
                        medias.add(new Media(line));
                    }
                }
            }
        }
        catch (Exception e)
        {
            exceptionHandler.handleException(e);
        }

        return medias;
    }

    public ArrayList<Media> importPLSList(String pPath)
    {
        ArrayList<Media> medias = new ArrayList<Media>();

        try
        {
            File file = new File(pPath);
            BufferedReader in = new BufferedReader(new FileReader(file));
            String line;

            while ((line = in.readLine()) != null)
            {
                if (line.startsWith("File"))
                {
                    File mediaFile = new File(line.substring(line.indexOf("=") + 1));

                    if (!mediaFile.isAbsolute())
                    {
                        medias.add(new Media(_convertToAbsolutePath(line, pPath)));
                    }
                    else
                    {
                        medias.add(new Media(mediaFile.getAbsolutePath()));
                    }
                }
            }
        }
        catch (Exception e)
        {
            exceptionHandler.handleException(e);
        }

        return medias;
    }

    private ArrayList<Media> _convertToMediaList(WplPlaylist pPlaylist, String pPath)
    {
        ArrayList<Media> mediaList = new ArrayList<Media>();
        ArrayList<WplPlaylist.Media> medias = pPlaylist.getBody().getSeq().getMedias();
        File playlist = new File(pPath);

        for (WplPlaylist.Media media : medias)
        {
            File mediaFile = new File(media.getSrc());

            if (!mediaFile.isAbsolute())
            {
                mediaList.add(new Media(playlist.getParent() + "\\" + media.getSrc()));
            }
            else
            {
                mediaList.add(new Media(media.getSrc()));
            }
        }

        return mediaList;
    }

    private String _convertToAbsolutePath(String pRelativePath, String pPlaylistPath)
    {
        int replaces = 0;
        String[] pathArray = pPlaylistPath.split("[\\\\]");
        StringBuilder pathToAdd = new StringBuilder();

        while (pRelativePath.startsWith(".." + File.separator))
        {
            pRelativePath = pRelativePath.replaceFirst("[.][.]" + Pattern.quote(File.separator), "");
            replaces++;
        }

        pathToAdd.setLength(0);

        for (int i = 0; i < pathArray.length - replaces - 1; i++)
        {
            pathToAdd.append(pathArray[i]).append(File.separator);
        }

        if (File.separator.equals("/"))
        {
            pathToAdd.insert(0, "/");
        }

        return pathToAdd.append(pRelativePath).toString();
    }
}
